package com.liuwei.msmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.liuwei.msmall.common.utils.PageUtils;
import com.liuwei.msmall.common.utils.Query;
import com.liuwei.msmall.product.common.enums.AttrTypeEnum;
import com.liuwei.msmall.product.dao.AttrAttrgroupRelationDao;
import com.liuwei.msmall.product.dao.AttrDao;
import com.liuwei.msmall.product.dao.AttrGroupDao;
import com.liuwei.msmall.product.dao.CategoryDao;
import com.liuwei.msmall.product.entity.AttrAttrgroupRelationEntity;
import com.liuwei.msmall.product.entity.AttrEntity;
import com.liuwei.msmall.product.entity.CategoryEntity;
import com.liuwei.msmall.product.entity.ProductAttrValueEntity;
import com.liuwei.msmall.product.service.AttrService;
import com.liuwei.msmall.product.service.CategoryService;
import com.liuwei.msmall.product.service.ProductAttrValueService;
import com.liuwei.msmall.product.vo.AttrVo;
import com.liuwei.msmall.product.vo.resp.AttrRespVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private AttrGroupDao attrGroupDao;

    @Resource
    private CategoryService categoryService;

    @Resource
    private ProductAttrValueService attrValueService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(String type, Long cateId, Map<String, Object> params) {

        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();

        if ("base".equals(type)){
            queryWrapper.eq(AttrEntity::getAttrType, AttrTypeEnum.ATTR_TYPE_BASE.getType());

        }else if ("sale".equals(type)){
            queryWrapper.eq(AttrEntity::getAttrType, AttrTypeEnum.ATTR_TYPE_SALE.getType());
        }

        if (cateId!=0){
            queryWrapper.eq(AttrEntity::getCatelogId,cateId);
        }

        String key = (String) params.get("key");

        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and((entityQueryWrapper) -> {
                entityQueryWrapper.like(AttrEntity::getAttrName, key).or().eq(AttrEntity::getAttrId, key);
            });
        }


        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> attrEntities = page.getRecords();

        List<AttrRespVo> attrRespVos = attrEntities.stream().map(attrEntity -> {

            AttrRespVo respVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, respVo);
            //判断是基本属性还是销售属性，销售属性没有分组信息
            if (attrEntity.getAttrType() == AttrTypeEnum.ATTR_TYPE_BASE.getType()) {
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = attrAttrgroupRelationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", respVo.getAttrId()));
                //设置分组名字
                if (Objects.nonNull(attrAttrgroupRelationEntity)) {
                    String attrGroupName = attrGroupDao.selectById(attrAttrgroupRelationEntity.getAttrGroupId()).getAttrGroupName();
                    respVo.setGroupName(attrGroupName);
                }
            }

            //设置分类信息
            CategoryEntity categoryEntity = categoryDao.selectById(respVo.getCatelogId());
            if (Objects.nonNull(categoryEntity)) {
                respVo.setCatelogName(categoryEntity.getName());
            }

            return respVo;
        }).collect(Collectors.toList());

        pageUtils.setList(attrRespVos);
        return pageUtils;
    }

    @Transactional
    @Override
    public void saveDetail(AttrVo attr) {

        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);

        this.save(attrEntity);

        AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
        attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
        attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());

        attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
    }

    /**
     * 通过id批量查询
     * @param attrIds
     * @return
     */
    @Override
    public List<AttrVo> getAttrInfoByIds(List<Long> attrIds) {
        List<AttrVo> vos =  Lists.newArrayList();

        if (CollectionUtils.isEmpty(attrIds)){
            return vos;
        }

        List<AttrEntity> entities = this.baseMapper.selectBatchIds(attrIds);

        if (CollectionUtils.isEmpty(entities)){
            return vos;
        }
        entities.stream().forEach(i->{
            AttrVo attrVo = new AttrVo();
            BeanUtils.copyProperties(i,attrVo);
            vos.add(attrVo);
        });
        return vos;
    }

    @Override
    public PageUtils getNoAttrRelationPage(List<Long> attrIds, Map<String, Object> params) {

        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.notIn(!CollectionUtils.isEmpty(attrIds),AttrEntity::getAttrId, attrIds);
        String key =(String) params.get("key");
        if (StringUtils.isNotBlank(key)){
            wrapper.like(AttrEntity::getAttrName,key).or()
                    .eq(AttrEntity::getAttrId,key);
        }

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    @Override
    public AttrRespVo getAttrInfoById(Long attrId) {

        AttrRespVo vo = new AttrRespVo();
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity,vo);
        Long[] catePath = categoryService.getCatePathById(attrEntity.getCatelogId());
        vo.setCatelogPath(catePath);


        if (attrEntity.getAttrType() == AttrTypeEnum.ATTR_TYPE_BASE.getType()){
            //基础属性返回所属分组
            AttrAttrgroupRelationEntity relationEntity = attrAttrgroupRelationDao.selectOne(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq(AttrAttrgroupRelationEntity::getAttrId, attrId));
            vo.setAttrGroupId(relationEntity.getAttrGroupId());
        }else if (attrEntity.getAttrType() == AttrTypeEnum.ATTR_TYPE_SALE.getType()){
            //销售属性，不需要返回

        }

        return vo;
    }

    @Transactional
    @Override
    public void updateAttr(AttrVo attr) {
        //更新自己
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        this.updateById(attrEntity);

        //如果是基础属性,更新属性和分组关系表
        if (attr.getAttrType() == AttrTypeEnum.ATTR_TYPE_BASE.getType()){

            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();

            attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());

            attrAttrgroupRelationDao.update(attrAttrgroupRelationEntity
                    ,new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq(AttrAttrgroupRelationEntity::getAttrId,attr.getAttrId()));
        }


    }

    @Override
    public List<AttrVo> getAttrListByGroupId(Long attrGroupId) {

        List<AttrAttrgroupRelationEntity> entities = attrAttrgroupRelationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId));

        if (CollectionUtils.isEmpty(entities)){
            return Lists.newArrayList();
        }
        List<Long> attrIds = entities.stream().map(i -> i.getAttrId()).collect(Collectors.toList());
        return getAttrInfoByIds(attrIds);
    }

    @Override
    public Map<Long, AttrEntity> getAttrInfoMapByIds(List<Long> attrIds) {

        Map<Long, AttrEntity> collect = this.baseMapper.selectList(new LambdaQueryWrapper<AttrEntity>().in(AttrEntity::getAttrId, attrIds))
                .stream().collect(Collectors.toMap(i -> i.getAttrId(), v -> v));
        return collect;
    }

    @Override
    public List<ProductAttrValueEntity> getBaseAtttrListBySpuId(Long spuId) {

        List<ProductAttrValueEntity> list = attrValueService.list(new LambdaQueryWrapper<ProductAttrValueEntity>().eq(ProductAttrValueEntity::getSpuId, spuId));
        return list;
    }

    @Override
    public void updateBaseAttrBySpuId(Long spuId,List<ProductAttrValueEntity> attrs) {

        if(!CollectionUtils.isEmpty(attrs)){
            attrs.stream().forEach(item->{
                item.setSpuId(spuId);
                attrValueService.update(item,new LambdaQueryWrapper<ProductAttrValueEntity>()
                        .eq(ProductAttrValueEntity::getSpuId,spuId).eq(ProductAttrValueEntity::getAttrId,item.getAttrId()));
            });
        }

    }

    @Override
    public List<AttrEntity> getSearchAttrByIds(List<Long> attrids) {
        if (CollectionUtils.isEmpty(attrids)){
            return Lists.newArrayList();
        }
        List<AttrEntity> attrEntities = this.getBaseMapper().selectList(new LambdaQueryWrapper<AttrEntity>()
                .in(AttrEntity::getAttrId, attrids).eq(AttrEntity::getSearchType,1));
        return attrEntities;
    }


}
